#! /usr/bin/env Python3
#coding=utf-8

"""
自己编写的与操作系统相关的函数
作者: KydGroups
版本: 1.0.0
完成日期: 2024-02-23
修改记录:
"""
from datetime import datetime
from datetime import timedelta
import platform #导入系统平台模块
import os


def SystemPlatform():
    """
    :DESCRIPTION:
        获取当前系统平台
    :PARAMS:
        nothings
    :RETURNS:
        当前系统平台,'Linux'或'Windows'
    """
    return platform.system()


def SystemBit():
    """
    :DESCRIPTION:
        获取当前系统的位数
    :PARAMS:
        nothings
    :RETURNS:
        当前系统的位数,32或64
    """
    return 32 if platform.architecture()[0] == '32bit' else 64


def SystemVersion():
    """
    :DESCRIPTION:
        获取当前系统的版本
    :PARAMS:
        nothings
    :RETURNS:
        当前系统的版本,如'4.0.0'
    """
    return platform.version()


def CurDate(bSqlStr:bool=True):
    """
    :DESCRIPTION:
        获取当前系统的日期
    :PARAMS:
        bSqlStr: 是否返回Sql字符串日期YYYY-MM-DD格式,如果不是则返回python日期类型
    :RETURNS:
        当前系统的日期,以YYYY-MM-DD格式
    """
    clsNow = datetime.now() #获取当前系统时间
    if bSqlStr: #如果返回SqlStr格式
        strNow = datetime.strftime(clsNow, "%Y-%m-%d") #转换为字符串格式
        return strNow
    else:
        return clsNow


def CurDateTime(bSqlStr:bool=True):
    """
    :DESCRIPTION
        获取当前系统的时间
    :PARAMS:
        bSqlStr: 是否返回Sql字符串日期时间YYYY-MM-DD HH:MM:SS格式,如果不是则返回python日期时间类型
    :RETURNS:
        当前系统的时间,以YYYY-MM-DD HH:MM:SS格式
    """
    clsNow = datetime.now() #获取当前系统时间
    if bSqlStr:
        strNow = datetime.strftime(clsNow, "%Y-%m-%d %H:%M:%S") #转换为字符串格式
        return strNow
    else:
        return clsNow


def CurTime(bSqlStr:bool=True):
    """
    :DESCRIPTION
        获取当前系统的时间
    :PARAMS:
        bSqlStr: 是否返回Sql字符串时间HH:MM:SS格式,如果不是则返回python日期时间类型
    :RETURNS:
        当前系统的时间,以HH:MM:SS格式
    """
    clsNow = datetime.now() #获取当前系统时间
    if bSqlStr:
        strNow = datetime.strftime(clsNow, "%H:%M:%S") #转换为字符串格式
        return strNow
    return clsNow


def DateBeforeDays(dateInput, nDays:int=1, bSqlStr:bool=True):
    """
    :DESCRIPTION
        获取当前系统的前n天日期
    :PARAMS:
        dateInput: 输入的日期格式,如果没有输入的字符串则会转换为python日期格式,如果没有输入则使用系统当前日期
        nDays: 获取前n天日期,默认1;如果<=0则返回None
        bSqlStr: 是否返回Sql字符串日期YYYY-MM-DD格式,如果不是则返回python日期时间类型
    :RETURNS:
        None:参数错误 Else:当前系统的前n天日期,以YYYY-MM-DD格式
    """
    if nDays <= 0: #输入的天数错误
        return None
    try:
        clsDate = None #保存日期格式
        if not dateInput: #如果没有输入日期,则使用当前日期
            clsDate = datetime.now()
        else:
            if isinstance(dateInput, str): #如果输入的是字符串格式
                clsDate = datetime.strptime(dateInput, "%Y-%m-%d")
            else: #其它情况都以python日期类型处理
                clsDate = dateInput
        clsDel = timedelta(days=nDays) #日期差值
        clsBefore = clsDate - clsDel #计算前nDays天的日期
        if bSqlStr: #如果需要返回SqlStr日期格式
            return datetime.strftime(clsBefore, "%Y-%m-%d")
        else:
            return clsBefore
    except:
        return None


def DateAfterDays(dateInput, nDays:int=1, bSqlStr:bool=True):
    """
    :DESCRIPTION
        获取当前系统的后n天日期
    :PARAMS:
        dateInput: 输入的日期格式,如果没有输入的字符串则会转换为python日期格式,如果没有输入则使用系统当前日期
        nDays: 获取前n天日期,默认1;如果<=0则返回None
        bSqlStr: 是否返回Sql字符串日期YYYY-MM-DD格式,如果不是则返回python日期时间类型
    :RETURNS:
        当前系统的后n天日期,以YYYY-MM-DD格式
    """
    if nDays <= 0: #输入的天数错误
        return None
    try:
        clsDate = None #保存日期格式
        if not dateInput: #如果没有输入日期,则使用当前日期
            clsDate = datetime.now()
        else:
            if isinstance(dateInput, str): #如果输入的是字符串格式
                clsDate = datetime.strptime(dateInput, "%Y-%m-%d")
            else: #其它情况都以python日期类型处理
                clsDate = dateInput
        clsDel = timedelta(days=nDays) #日期差值
        clsBefore = clsDate + clsDel #计算后nDays天的日期
        if bSqlStr: #如果需要返回SqlStr日期格式
            return datetime.strftime(clsBefore, "%Y-%m-%d")
        else:
            return clsBefore
    except:
        return None


def DateIntervalDays(firstDate, secondDate):
    """
    :DESCRIPTION
        计算两个日期间隔多少天
    :PARAMS:
        firstDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
        secondDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
    :RETURNS:
        Int:相差的天数
    """
    try:
        clsFirst = None #第一个日期
        clsSecond = None #第二个日期
        if not firstDate: #如果没有输入第一个日期,则使用系统默认的日期
            clsFirst = datetime.now()
        else:
            if isinstance(firstDate, str): #如果输入的是字符串格式
                clsFirst = datetime.strptime(firstDate, "%Y-%m-%d")
            else: #其它情况都按python日期类型处理
                clsFirst = firstDate

        if not secondDate: #如果没有输入第二个日期,则使用系统默认的日期
            clsSecond = datetime.now()
        else:
            if isinstance(secondDate, str): #如果输入的是字符串格式
                clsSecond = datetime.strptime(secondDate, "%Y-%m-%d")
            else: #其它情况都按python日期类型处理
                clsSecond = secondDate
        clsDel = clsFirst - clsSecond
        nDays = abs(clsDel.days) #对天数取绝对值
        return nDays
    except:
        return None


def DateInSameMonth(firstDate, secondDate):
    """
    :DESCRIPTION:
        判断两个日期是否在同一个月份中
    :PARAMS:
        firstDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
        secondDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
    :RETURNS:
        True:同一个月份  else False
    """
    strFirst = "" #保存第一个日期的字符串格式
    strSecond = "" #保存第二个日期的字符串格式
    try:
        if not firstDate: #如果没有输入第一个日期,则使用系统当前日期
            strFirst = datetime.strftime(datetime.now(), "%Y-%m-%d")
        else: #如果输入了第一个日期
            if isinstance(firstDate, str): #如果是字符串格式
                strFirst = firstDate
            else: #否则为python日期类型,则转换为字符串格式
                strFirst = datetime.strftime(firstDate, "%Y-%m-%d")

        if not secondDate: #如果没有输入第二个日期,则使用系统当前日期
            strSecond = datetime.strftime(datetime.now(), "%Y-%m-%d")
        else: #如果输入了第二个日期
            if isinstance(secondDate, str): #如果是字符串格式
                strSecond = secondDate
            else: #否则为python日期类型
                strSecond = datetime.strftime(secondDate, "%Y-%m-%d")

        if (strFirst[:7] == strSecond[:7]):#分隔字符串取出月份,判断是否相同
            return True
        else:
            return False
    except:
        return False


def DateInSameWeek(firstDate, secondDate):
    """
    :DESCRIPTION:
        判断两个日期是否在同一个星期中
    :PARAMS:
        firstDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
        secondDate:如果是字符串则使用格式YYYY-MM-DD,否则为python日期格式,如果没有输入则使用系统当前日期
    :RETURNS:
        True:同一个星期  else False
    """
    firstCal = None #保存第一个日期日历格式
    secondCal = None #保存第二个日期日期格式
    try:
        if not firstDate: #如果没有输入第一个日期,则使用系统当前日期
            firstCal = datetime.now().isocalendar()
        else: #如果输入了第一个日期
            if isinstance(firstDate, str): #如果是字符串格式
                firstCal = datetime.strptime(firstDate, "%Y-%m-%d").isocalendar() #转换格式
            else: #否则为python日期类型,则转换为字符串格式
                firstCal = firstDate.isocalendar()

        if not secondDate: #如果没有输入第二个日期,则使用系统当前日期
            secondCal = datetime.now().isocalendar()
        else: #如果输入了第二个日期,则转换为字符串格式
            if isinstance(secondDate, str): #如果是字符串格式
                secondCal = datetime.strptime(secondDate, "%Y-%m-%d").isocalendar() #转换格式
            else: #否则为python日期类型,则转换为字符串格式
                secondCal = secondDate.isocalendar()

        if ((firstCal[0] == secondCal[0]) and (firstCal[1] == secondCal[1])):#如果两个日期的年和第N周都相同
            return True
        else:
            return False
    except:
        return False


def PriorChoiceFile(filePrior:str='', fileSpare:str=''):
    """
    :DESCRIPTION:
        判断优先文件中否存在,如果存在返回文件路径,否则判断备份文件是否存在,如果存在返回备份文件路径,否则返回None
    :PARAMS:
        filePrior: 优先选择的文件
        fileSpare: 备份选择的文件
    :RETURNS:
        None:文件都不存在 Str:存在的文件路径
    """
    try:
        if isinstance(filePrior, str): #判断传入的优先文件参数是否为字符串
            if len(filePrior) >= 1: #文件名满足最小长度条件
                if os.path.exists(filePrior): #如果文件存在
                    return filePrior

        if isinstance(fileSpare, str): #优先文件判定失败,判断传入的备选文件参数是否为字符串
            if len(fileSpare) >= 1: #文件名满足最小长度
                if os.path.exists(fileSpare): #如果文件存在
                    return fileSpare

        return None #两个文件都判定失败,返回None
    except: #出错
        return None


def TraverseDirectory(directory:str='', prefix:str='', suffix:str='', bAddDir:bool=False, bReSub:bool=False):
    """
    :DESCRIPTION:
        遍历目录,生成文件名列表
    :PARAMS:
        directory:目录名称（例如["/usr/local/bin", "./usr/bin"]）
        prefix:目标文件名的前缀,如果设置则判断
        suffix:目标文件名的后缀,如果设置则判断
        bAddDir:是否在返回的文件名中添加目录路径
        bReSub: 是否递归遍历子目录
    :RETURNS:
        None:没有数据返回 List:文件名列表
    """
    try:
        if not directory: #如果没有传入目录参数
            return None

        if not os.path.exists(directory): #如果目录不存在
            return None

        nPreLen = 0 #前缀长度
        nSufLen = 0 #后缀长度
        if not prefix: #如果没有设置检查前缀
            pass
        else:
            nPreLen = len(prefix) #计算前缀长度
        if not suffix: #如果没有设置检查后缀
            pass
        else:
            nSufLen = len(suffix) #计算后缀长度

        listReturn = list()
        for root, dirs, files in os.walk(directory): #调用walk遍历目录,该函数默认会递归遍历子目录
            if not bReSub: #如果不递归遍历子目录
                if root != directory: #如果当前遍历的目录不是传入的目录
                    break #中断目录循环
            for file in files: #遍历目录下的文件名
                if nPreLen >= 1: #如果需要检查前缀
                    if (len(file) < nPreLen) or (file[:nPreLen] != prefix): #如果文件名前缀不符合条件
                        continue #跳过此文件

                if nSufLen >= 1: #如果需要检查后缀
                    if (len(file) < nSufLen) or (file[-nSufLen:]!= suffix):#如果后缀不符合条件
                        continue #跳过此文件

                fileTemp = "" #临时用文件名
                if bAddDir: #如果需要添加目录名
                    fileTemp = os.path.join(root, file)
                else:
                    fileTemp = file
                listReturn.append(fileTemp)
        return listReturn
    except:
        return None


def ConsoleCmdCleanScreen():
    """
    :DESCRIPTION
        系统控制台命令清除屏幕显示内容
    :Returns 无
    """
    try:
        strPlatform = SystemPlatform()
        if strPlatform == 'Windows':
            os.system("cls")
        else:
            os.system("clear")
        return True
    except:
        return None
